#include "manage.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

void AddBook_List(BookList * L,Book * B);
// 向表中增加元素

bool Book_Exit(BookList * L,char isbn[],BookLinkList ** B);
// 判断书本是否存在
// 存在 - 通过B返回表中对应节点

void Destroy_BookLinkList(BookLinkList *B);
//

void AddReader_List(BookLinkList * L,Reader * R);
// 向表中增加借阅者

void SaveReader(BookLinkList * L,FILE * save);
// 保存借阅者信息

#define ERROR_NUM 3
static int error_num=ERROR_NUM;
// 允许输入错误的次数

BookList * Init_BookList(){
	FILE * BookData=fopen(DATA_FILE,"r");
	BookList * NewList;
	char ch[128];
	NewList=(BookList *)malloc(sizeof(BookList));
	NewList->List=NULL;
	NewList->Num=0;
	if(BookData == NULL){ // 记录文件不存在
		return NewList;
	}
	Book * NewBook;
	unsigned int Num;
	while(!feof(BookData)){
		fscanf(BookData,"%s",ch); // 标记
		if(strcmp(ch,"#END") == 0){ // #END 表示结束
			break;
		}else{
			NewBook=Init_Book();
		}
		fscanf(BookData,"%s",ch); // ISBN码
		SetISBN(NewBook,ch);
		fscanf(BookData,"%s",ch); // Name
		SetName(NewBook,ch);
		fscanf(BookData,"%s",ch); // 作者
		SetAuthor(NewBook,ch);
		fscanf(BookData,"%u",&Num); // 存量
		SetStock(NewBook,Num);
		fscanf(BookData,"%u",&Num); // 总量
		SetTotal(NewBook,Num);
		while(true){    // 借阅者 '#'表示结束
			fscanf(BookData,"%s",ch);
			if(strcmp(ch,"#") == 0)
				break;
			Reader * R=InitReader();
			SetName_Reader(R,ch); // 借阅者姓名
			fscanf(BookData,"%s",ch);
			SetId_Reader(R,ch);
			int y,m,d;
			fscanf(BookData,"%d",&y);
			fscanf(BookData,"%d",&m);
			fscanf(BookData,"%d",&d);
			SetReturnTime(R,y,m,d);
			AddReader(NewBook,R);
		}

		AddBook_List(NewList,NewBook);
		NewList->Num++;
	}
	fclose(BookData);
	return NewList;
}
void AddBook_List(BookList * L,Book * B){
	BookLinkList * newlink;
	newlink=(BookLinkList *)malloc(sizeof(BookLinkList));
	newlink->Book=B;
	newlink->next=L->List;
	L->List=newlink;
}
void Add_Book(BookList * L){
	char ch[128];
	Book * NewBook;
	BookLinkList * B;
	int num;
	printf("新增书籍：\n");
	printf("ISBN (13): ");
	while( !GetISBN(ch)){
		if(error_num == 0){ // 限制输入错误的次数
			error_num=ERROR_NUM;
			return;
		}
		printf("请重新输入 ISBN: ");
		error_num--;
	}
	if(Book_Exit(L,ch,&B)){
		// 书籍已存在，更新库存
		printf("现有库存：%u\n",B->Book->Total);
		printf("新增库存数量：");
		scanf("%u",&num);
		clear_buffer();
		B->Book->Total += num; // 库存量和现存量同时增加
		B->Book->Stock += num;
		return;
	}
	// 书籍不存在，录入其他信息
	NewBook=Init_Book();
	SetISBN(NewBook,ch);
	printf("书 名: ");
	scanf("%s",ch);
	SetName(NewBook,ch);
	printf("作 者: ");
	scanf("%s",ch);
	SetAuthor(NewBook,ch);
	unsigned int stock=0,total=0;
	do{
		if(error_num == 0){
			error_num=ERROR_NUM;
			Destroy_Book(NewBook);
			return;
		}
		if(total < stock)
			printf("总数大于存量，请重新输入！\n");
		printf("现存量: ");
		scanf("%u",&stock);
		clear_buffer();
		printf("库存量: ");
		scanf("%u",&total);
		clear_buffer();
		error_num--;
	}while(stock > total);
	SetStock(NewBook,stock);
	SetTotal(NewBook,total);
	AddBook_List(L,NewBook);
}

bool Book_Exit(BookList * L,char isbn[],BookLinkList ** B){
	BookLinkList * Find;
	Find=L->List;
	while(Find != NULL){
		int i=strcmp(Find->Book->ISBN,isbn);
		if(i == 0) {
			*B=Find;
			return true;
		}
		Find=Find->next;
	}
	return false;
}

void Brrow_Book(BookList * L){
	char ch[128];
	printf("请输入要借的书的ISBN码：");
	while(!GetISBN(ch)){
		if(error_num == 0){
			error_num=ERROR_NUM;
			return;
		}
		printf("请重新输入 ISBN(13): ");
		error_num--;
	}
	BookLinkList * S;
	if(!Book_Exit(L,ch,&S)){
		fprintf(stderr,"该书籍不在仓库中\n");
		return;
	} else{
		if(S->Book->Stock == 0) {
			printf("《%s》的库存为0，无法借出。\n", S->Book->Name);
			return;
		}
	}
	printf("======================\n");
	Show_Book(S->Book);
	printf("======================\n");
	printf("借书证(11)：");
	while( !GetId_Reader(ch)){
		if(error_num == 0){
			error_num=ERROR_NUM;
			return;
		}
		printf("请重新输入借书证号: ");
		error_num--;
	}
	Reader * NewReader;
	NewReader=InitReader();
	SetId_Reader(NewReader,ch);
	printf("姓  名：");
	scanf("%s",ch);
	SetName_Reader(NewReader,ch);
	printf("请输入归还的时间 (xxxx xx xx)：");
	int y,m,d;
	scanf("%d %d %d",&y,&m,&d);
	clear_buffer();
	while (!SetReturnTime(NewReader,y,m,d)){
		printf("请重新输入归还时间：");
		scanf("%d %d %d",&y,&m,&d);
		clear_buffer();
	}
	AddReader_List(S,NewReader);
	S->Book->Stock--;
}

void Save_BookList(BookList * B){
	BookLinkList * list=B->List;
	FILE * bookdata=fopen(DATA_FILE,"w");
	while(list != NULL){
		fprintf(bookdata,"###\n");
		fprintf(bookdata,"%s\n",list->Book->ISBN);
		fprintf(bookdata,"%s\n",list->Book->Name);
		fprintf(bookdata,"%s\n",list->Book->Author);
		fprintf(bookdata,"%d\n",list->Book->Stock);
		fprintf(bookdata,"%d\n",list->Book->Total);
		// 打印借阅者列表
		SaveReader(list,bookdata);
		list=list->next;
	}
	fprintf(bookdata,"#END");
}

void SaveReader(BookLinkList * L,FILE * save){
	Reader * Rlist=L->Book->ReaderList;
	while(Rlist != NULL){
		fprintf(save,"%s ",Rlist->Name);
		fprintf(save,"%s ",Rlist->ID);
		fprintf(save,"%d ",Rlist->Year);
		fprintf(save,"%d ",Rlist->Month);
		fprintf(save,"%d\n",Rlist->Day);
		Rlist=Rlist->Next;
	}
	fprintf(save,"#\n");
}

void Return_Book(BookList * L){
	char ch[128];
	printf("请输入要归还的图书的ISBN: ");
	while( !GetISBN(ch)){
		if(error_num == 0){
			error_num=ERROR_NUM;
			return;
		}
		printf("请重新输入 ISBN: ");
		error_num--;
	}
	BookLinkList * list;
	if(!Book_Exit(L,ch,&list)){
		fprintf(stderr,"ISBN码为%s的书籍不存在！\n",ch);
		return;
	}
	printf("======================\n");
	Show_Book(list->Book);
	printf("======================\n");
	printf("借书证(11)：");
	while( !GetId_Reader(ch)){
		if(error_num == 0){
			error_num=ERROR_NUM;
			return;
		}
		printf("请重新输入借书证号(11)：");
		error_num--;
	}
	if(!Delete_Reader(&(list->Book->ReaderList),ch)){
		fprintf(stderr,"没有找到借书证号为 %s 的借阅者\n",ch);
		return; // 失败后之后直接退出
	}
	list->Book->Stock++;
	printf("还书成功！\n");
}

void List_Book(BookList * L){
	BookLinkList * list=L->List;
	while(list != NULL){
		Show_Book(list->Book);
		printf("===========================\n");
		list=list->next;
	}
}
void AddReader_List(BookLinkList * L,Reader * R){
	R->Next=L->Book->ReaderList;
	L->Book->ReaderList=R;
}

void Destroy_BookList(BookList * B){
	Destroy_BookLinkList(B->List);
	free(B);
}
void Destroy_BookLinkList(BookLinkList *B){
	BookLinkList * del;
	while(B != NULL){
		del=B;
		Destroy_Book(B->Book);
		B=B->next;
		free(del);
	}
}

#undef DATA_FILE
#undef ERROR_NUM
